package com.appleyk.mybatis.v1.factorybean;

import com.appleyk.mybatis.annotation.MySelect;
import com.appleyk.mybatis.model.User;
import com.appleyk.mybatis.v1.mapper.UserMapper;
import org.springframework.beans.factory.FactoryBean;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * <p>越努力，越幸运</p>
 *
 * @author appleyk
 * @version V.0.1.1
 * @blob https://blog.csdn.net/appleyk
 * @date created on  12:42 上午 2020/12/12
 */
public class UserMapperFactoryBean implements FactoryBean<UserMapper> {

    @Override
    public Class<?> getObjectType() {
        return UserMapper.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

    // 注意这里不是真正返回UserMapper的实例啊，也不可能返回，因为它是接口类型的，实例化不了
    // 怎么办呢，那我就用一个代理对象来代替它，代替它干什么呢，当然是代替它干一些和数据库（JDBC）打交道的事情了
    // 比如执行sql的查询等...etc
    @Override
    public UserMapper getObject() throws Exception {
        return (UserMapper) Proxy.newProxyInstance(UserMapper.class.getClassLoader(),
                new Class[]{UserMapper.class}, new UserMapperInvocation());
    }

    class UserMapperInvocation implements InvocationHandler {
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            // 判断下，当前是不是自己调用的，如果是自己，直接调用自己的方法
            if (method.getDeclaringClass().equals(this)) {
                return method.invoke(args);
            }
            // 否则增强方法，先拿到注解的sql值
            MySelect annotation = method.getAnnotation(MySelect.class);
            String sql = annotation.value();
            // 再拿到参数，假设只有一个
            Long uid = (Long)args[0];
            sql = sql.replace("?", uid.toString());
            System.out.println("=== 开始执行sql语句："+sql);
            // 假设查询到了，这里我们自己模拟一个，也就是new一个
            return new User(uid,"余坤",18);
        }
    }
}
